package com.autumn.platform.web.resulthandler.context.impl;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.method.HandlerMethod;

import com.autumn.platform.core.spring.SpringHolder;
import com.autumn.platform.web.resulthandler.context.HandlerMethodContext;
import com.autumn.platform.web.resulthandler.context.HandlerMethodContextHolder;

public class HandlerMethodContextImpl implements HandlerMethodContext {

    private final HandlerMethod handlerMethod;

    private final Object[] args;

    private final Throwable throwable;

    private final Object result;

    private final long startTime;

    private final long endTime;

    public HandlerMethodContextImpl(Object[] args, Object result, Throwable throwable, long startTime, long endTime) {
        this.handlerMethod = HandlerMethodContextHolder.getHandlerMethod();
        this.args = args;
        this.throwable = throwable;
        this.result = result;
        this.startTime = startTime;
        this.endTime = endTime;
    }

    @Override
    public Map<String, Object> asMap() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("handlerMethod", handlerMethod);
        map.put("args", args);
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        if (null != result) {
            map.put("result", result);
        }
        if (null != throwable) {
            map.put("exception", throwable);
        }
        return map;
    }

    @Override
    public boolean isSuccess() {
        return null == this.throwable;
    }

    @Override
    public HandlerMethod getHandlerMethod() {
        return this.handlerMethod;
    }

    @Override
    public Object[] getArgs() {
        return args;
    }

    @Override
    public <T> T getArg(int index, Class<T> cls) {
        return SpringHolder.convert(args[index], cls);
    }

    @Override
    public long getStartTime() {
        return startTime;
    }

    @Override
    public long getEndTime() {
        return endTime;
    }

    @Override
    public Throwable getThrowable() {
        return throwable;
    }

    @Override
    public <T> T getResult(Class<T> cls) {
        if (null == result) {
            return null;
        }
        return SpringHolder.convert(result, cls);
    }
}
